<?php
/**
 * oloDB :: Simple & Easy database layer abstraction.
 * Note: currently support only MySQL and MySQLi.
 * @author Surachet Monchawanon <admin@sukung.com>
 * @version 1.0
 * @package olo
 */    
class oloDB {

    const USE_MYSQL = 1;
    const USE_MYSQLI = 2;
    const MAX_DRIVER = 2;

    const RS_FULL = 1;
    const RS_SINGLE = 2;
    const RS_VALUE = 3;

    const ERR_NODBSELECT = "No database select.";
    const ERR_SETDRIVER = "Invalid Driver. Try using ";
    const ERR_CONNECT = "Database connection failed.";
    const ERR_QUERY = "Failed to perform query.";
    const ERR_ARRAYFORMAT = "Invalid array format.";

    private static $_connection;
    private static $_driver = self::USE_MYSQLI;

    function setDriver($driver) {
        if($driver < 0 || $driver > MAX_DRIVER){
            self::$_driver = self::USE_MYSQL;
        } else {
            self::$_driver = $driver;
        }
        return true;
    }

    function connect($database,$hostname = "localhost",$username = "root",$password = ""){
        if(trim($database) == ""){
            throw new Exception (self::ERR_NODBSELECT);
        }
        switch(self::$_driver){
            case self::USE_MYSQL:
                self::$_connection = @mysql_connect($hostname,$username,$password);
                if(!self::$_connection) {
                    throw new Exception (self::ERR_CONNECT);
                } else {
                    if(!mysql_select_db($database,self::$_connection)){
                        throw new Exception (self::ERR_NODBSELECT);
                    }
                }
                break;
            case self::USE_MYSQLI:
                self::$_connection = @mysqli_connect($hostname,$username,$password,$database);
                if(!self::$_connection) {
                    throw new Exception (self::ERR_CONNECT);
                } else {
                    if(!mysqli_select_db(self::$_connection,$database)){
                        throw new Exception (self::ERR_NODBSELECT);
                    }
                }
                break;
        }
        return true;
    }

    function insert($table,$array){
        if(!is_array($array)){
            throw new Exception (self::ERR_ARRAYFORMAT);
        }
        if(count($array) < 1) {
            throw new Exception (self::ERR_ARRAYFORMAT);
        }
        $keys = implode(",",array_keys($array));
        $values = implode("','",array_values($array));
        self::query("INSERT INTO {$table} ({$keys}) VALUES ('{$values}')");
        switch(self::$_driver){
            case self::USE_MYSQL:
                return mysql_insert_id(self::$_connection);
            case self::USE_MYSQLI:
                return mysqli_insert_id(self::$_connection);
        }
    }

    function delete($table,$condition = ""){
        $condition = $condition == "" ? "" : " WHERE " . $condition;
        self::query("DELETE FROM {$table} {$condition}");
        switch(self::$_driver){
            case self::USE_MYSQL:
                return mysql_affected_rows(self::$_connection);
            case self::USE_MYSQLI:
                return mysqli_affected_rows(self::$_connection);
        }
    }

    function update($table,$array,$condition = ""){
        if(!is_array($array)){
            throw new Exception (self::ERR_ARRAYFORMAT);
        }
        if(count($array) < 1) {
            throw new Exception (self::ERR_ARRAYFORMAT);
        }
        $condition = $condition == "" ? "" : " WHERE " . $condition;
        $list = array();
        foreach($array as $key=>$val){
            $list[] = "{$key} = '{$val}'";
        }
        $value = implode(",",$list);
        self::query("UPDATE {$table} SET {$value} {$condition}");
        switch(self::$_driver){
            case self::USE_MYSQL:
                return mysql_affected_rows(self::$_connection);
            case self::USE_MYSQLI:
                return mysqli_affected_rows(self::$_connection);
        }
    }

    function select($table,$condition = "",$order = "",$limit = "",$page = 1){
        if(is_integer($condition)){
            $limit = $condition == "" ? "" : " LIMIT " . ((($order == "" ? 1 : $order) - 1) * $condition) . ",". $condition;
            $condition = "";
            $order = "";
        } elseif (is_integer($order)) {
            $limit = $order == "" ? "" : " LIMIT " . ((($limit == "" ? 1 : $limit) - 1) * $order) . ",". $order;
            $condition = $condition == "" ? "" : " WHERE " . $condition;
            $order = "";
        } else {
            $condition = $condition == "" ? "" : " WHERE " . $condition;
            $order = $order == "" ? "" : " ORDER " . $order;
            $limit = $limit == "" ? "" : " LIMIT " . (($page - 1) * $limit) . ",". $limit;
        }
        return self::query("SELECT * FROM {$table} {$condition} {$order} {$limit}");
    }

    function query($query,$rs_mode = self::RS_FULL){
        switch(self::$_driver){
            case self::USE_MYSQL:
                if($result = @mysql_query($query,self::$_connection)){
                    $ret = self::_resultProcess($result,$rs_mode);
                    @mysql_free_result($result);
                } else {
                    throw new Exception (self::ERR_QUERY . " [" . $query . "]");
                }
                break;
            case self::USE_MYSQLI:
                if($result = @mysqli_query(self::$_connection,$query)){
                    $ret = self::_resultProcess($result,$rs_mode);
                    @mysqli_free_result($result);
                } else {
                    throw new Exception (self::ERR_QUERY . " [" . $query . "]");
                }
                break;
        }
        return $ret;
    }

    function close(){
        switch(self::$_driver){
            case self::USE_MYSQL:
                @mysql_close(self::$_connection);
                break;
            case self::USE_MYSQLI:
                @mysqli_close(self::$_connection);
                break;
        }
    }

    private function _resultProcess($result,$rs_mode){
        $list = array();
        switch(self::$_driver){
            case self::USE_MYSQL:
                $func_fetch_row = "mysql_fetch_row";
                $func_fetch_assoc = "mysql_fetch_assoc";
                break;
            case self::USE_MYSQLI:
                $func_fetch_row = "mysqli_fetch_row";
                $func_fetch_assoc = "mysqli_fetch_assoc";
                break;
        }
        if($result === false) {
            throw new Exception (self::ERR_QUERY);
        } elseif($result === true) {
            return true;
        } else {
            switch($rs_mode){
                case self::RS_FULL:
                    while($row = $func_fetch_assoc($result)){
                        $list[] = $row;
                    }
                    return $list;
                    break;
                case self::RS_SINGLE:
                    $row = $func_fetch_assoc($result);
                    return $row;
                    break;
                case self::RS_VALUE:
                    $data = $func_fetch_row($result);
                    return $data[0];
                    break;
            }
        }
    }
}

?>